﻿using BackEnd;
using ICSharpCode.AvalonEdit.Highlighting;
using ICSharpCode.AvalonEdit.Highlighting.Xshd;
using System;
using System.ComponentModel;
using System.Data;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Xml;

namespace FrontEnd
{
	public partial class SQLQueryTab : TabItem
	{
		#region EVENTS
		public event EventHandler<Request> Request;
		#endregion

		#region PROPERTIES
		public static readonly DependencyProperty TitleProperty = DependencyProperty.Register("Title", typeof(string), typeof(SQLQueryTab), new PropertyMetadata("Query"));
		public string Title
		{
			get { return (string)GetValue(TitleProperty); }
			set
			{
				SetValue(TitleProperty, value);
				_header.Title = value;
			}
		}

		public static readonly DependencyProperty LastResultProperty = DependencyProperty.Register("LastResult", typeof(VectorResult), typeof(SQLQueryTab), new PropertyMetadata(null));
		public VectorResult LastResult
		{
			get { return (VectorResult)GetValue(LastResultProperty); }
			set { SetValue(LastResultProperty, value); }
		}

		public static readonly DependencyProperty IsModifiedProperty = DependencyProperty.Register("IsModified", typeof(bool), typeof(SQLQueryTab), new PropertyMetadata(false));
		public bool IsModified
		{
			get { return (bool)GetValue(IsModifiedProperty); }
			set { SetValue(IsModifiedProperty, value); }
		}
		#endregion

		#region CONSTRUCTOR(S)
		public SQLQueryTab()
		{
			InitializeComponent();

			// header
			_header = new ClosableTabHeader(this);
			_header.Closing += Closing;
			_header.Closed += Closed;
			this.Header = _header;

			// highlighting
			using (var str = this.GetType().Assembly.GetManifestResourceStream("FrontEnd.Resources.sql.xshd"))
			{
				using (var rdr = new XmlTextReader(str))
				{
					txtSQL.SyntaxHighlighting = HighlightingLoader.Load(rdr, HighlightingManager.Instance);
				}
			}

			txtSQL.TextChanged += TextChanged;
		}
		#endregion

		#region PUBLIC METHODS

		public void AssignResult(Result result)
		{
			if (result is VectorResult)
			{
				this.LastResult = (VectorResult)result;
				if(string.IsNullOrEmpty(_origSQL))
				{
					txtSQL.Text = ((DataRequest)result.Request).SQL;
					_origSQL = ((DataRequest)result.Request).SQL;
				}
			}
			else if (result is ScriptResult)
			{
				txtSQL.Text = ((ScriptResult)result).SQL;
				_origSQL = ((ScriptResult)result).SQL;
			}
		}

		#endregion

		#region PRIVATE METHODS

		private string GetExecutableSQL()
		{
			string sql = txtSQL.Text;
			if (txtSQL.SelectionLength > 0)
			{
				sql = txtSQL.SelectedText;
			}

			sql = sql.Trim();
			return sql;
		}

		private void CanExecute(object sender, CanExecuteRoutedEventArgs e)
		{
			e.CanExecute = !string.IsNullOrEmpty(GetExecutableSQL());
		}

		private void Execute(object sender, ExecutedRoutedEventArgs e)
		{
			var req = new DataRequest(this, GetExecutableSQL());
			OnRequest(req);
		}

		private void TextChanged(object sender, EventArgs e)
		{
			this.IsModified = txtSQL.Text != _origSQL && _origSQL != null;
		}

		private void Closing(object sender, CancelEventArgs e)
		{
			if (this.IsModified)
			{
				var dlg = MessageBox.Show("Save changes?", "SQLiter", MessageBoxButton.YesNoCancel, MessageBoxImage.Warning, MessageBoxResult.Yes);
				if (dlg == MessageBoxResult.Cancel)
				{
					e.Cancel = true;
				}
			}
		}

		private void Closed(object sender, EventArgs e)
		{
			var tabContainer = (TabControl)this.Parent;
			tabContainer.Items.Remove(this);
		}

		protected virtual void OnRequest(Request request)
		{
			if (Request != null)
				Request(this, request);
		}
		#endregion

		#region PRIVATE MEMBERS

		private ClosableTabHeader _header;
		private string _origSQL;

		#endregion
	}
}
